package com.source.lightfowl.labelingRecord.service;

import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.source.lightfowl.VO.BarcodeCountVO;
import com.source.lightfowl.VO.RecordVO;
import com.source.lightfowl.basedata.dao.PoultryCategoryDao;
import com.source.lightfowl.basedata.dao.SlaughterHouseDao;
import com.source.lightfowl.basedata.dao.StallsDao;
import com.source.lightfowl.basedata.dao.ToMarketDao;
import com.source.lightfowl.basedata.entity.PoultryCategory;
import com.source.lightfowl.basedata.entity.SlaughterHouse;
import com.source.lightfowl.basedata.entity.Stalls;
import com.source.lightfowl.basedata.service.PoultryCategoryService;
import com.source.lightfowl.basedata.service.SlaughterHouseService;
import com.source.lightfowl.handler.MyException;
import com.source.lightfowl.labelingRecord.dao.RecordDao;
import com.source.lightfowl.labelingRecord.pojo.Record;
import com.source.lightfowl.labelingRecord.pojo.vo.Info;
import com.source.lightfowl.labelingRecord.pojo.vo.PoultryCategoryVo;
import com.source.lightfowl.labelingRecord.pojo.vo.SlaughterVo;
import com.source.lightfowl.labelingRecord.pojo.vo.StallsVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


/**
 * 服务层
 * 
 * @author Administrator
 *
 */
@Service
public class RecordService {

	@Autowired
	private RecordDao recordDao;
	@Autowired
	private PoultryCategoryService poultryCategoryService;
	@Autowired
	private StallsDao stallsDao;
	@Autowired
	private SlaughterHouseDao slaughterHouseDao;
	@Autowired
	private PoultryCategoryDao poultryCategoryDao;
	@Autowired
	private ToMarketDao toMarketDao;

	/**
	 * 查询全部列表
	 * @return
	 */
	public List<RecordVO> findAll() {
		List<Record> list = recordDao.findAll();
		if (list == null){
			return null;
		}
		List<RecordVO> collect = new ArrayList<>();
		for (Record record:
			  list) {
				RecordVO recordVO = new RecordVO();
				BeanUtils.copyProperties(record, recordVO);
				Stalls stalls = stallsDao.findInfoById(record.getStallsId());
				if (stalls != null) {
					recordVO.setStallsName(stalls.getStallsName());
				}
				recordVO.setToMarketName(toMarketDao.findNameById(record.getToMarkId()));
				recordVO.setPoultryName(poultryCategoryDao.findNameById(record.getPoultryCategoryId()));
				collect.add(recordVO);
		}
		return collect;
	}

	public List<RecordVO> findAll(int page, int size) {
		Page<Record> list = recordDao.findAll(PageRequest.of(page-1, size));
		List<RecordVO> collect = list.stream().map(s -> {
			RecordVO vo = new RecordVO();
			BeanUtils.copyProperties(s, vo);

			Optional<PoultryCategory> optional = poultryCategoryService.findOptionalById(s.getPoultryCategoryId());
			if (optional.isPresent()){
				vo.setPoultryName(optional.get().getName());
			}

			return vo;
		}).collect(Collectors.toList());
		return collect;
	}


	/**
	 * 根据ID查询实体
	 * @param id
	 * @return
	 */
	public Record findById(BigInteger id) {
		return recordDao.findById(id).get();
	}


	/**
	 * 增加
	 * @param record
	 */
	public void add(Record record) {
		Calendar calendar= Calendar.getInstance();
		SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
		String tmp = dateFormat.format(calendar.getTime());
		try{
			Date data = dateFormat.parse(tmp);
			record.setCreateDate(data);
		}catch (ParseException e){
			System.out.println(e);
		}
		recordDao.save(record);
	}

	/**
	 * 修改
	 * @param record
	 */
	public void update(Record record) {
		recordDao.save(record);
	}

	/**
	 * 删除
	 * @param id
	 */
	public void deleteById(BigInteger id) {
		recordDao.deleteById(id);
	}


	public List<BarcodeCountVO> findByNameAndTime(String name, String startDate, String endDate) {

		//to do 8 贴标数量
		//SELECT * FROM labeling_record WHERE DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= DATE(LabelingDate)
		//SELECT * FROM labeling_record WHERE barcodeMachineId IN (23338) AND DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= DATE(LabelingDate)
		//1.根据档口名字或者联系人名字模糊匹配出档口id
		List<Integer> list = stallsDao.findIdByUserNameOrStallName(name);
		//2.查询出这些档口近一个月的条码
		List<Record> all = recordDao.findByBarcodeMaChineIdNearThirtyDay(list,startDate+" 00:00:00",endDate+" 23:59:59");
		//3.分类进行封装 封装成前端需要的格式
		ArrayList<BarcodeCountVO> vos = new ArrayList<>();
		getResult(list, all, vos);
		return vos;

	}

	private void getResult(List<Integer> list, List<Record> all, ArrayList<BarcodeCountVO> vos) {
		for (Integer i :list){
			String stallsName = stallsDao.findById(i).get().getStallsName();
			long count = all.stream().filter(s -> {
				return s.getStallsId().equals(i + ""); //id匹配的
			}).count();
			vos.add(new BarcodeCountVO(stallsName,count));
		}
	}

	//默认查询全部档口一个月的
	public List<BarcodeCountVO> findByNameAndTime() {
		//to do 默认查询全部档口一个月的
		List<Stalls> all = stallsDao.findAll();  //全部档口
		List<Integer> list = all.stream().map(s -> {
			return s.getId();
		}).collect(Collectors.toList()); //获取全部档口的id

		List<Record> records = recordDao.findByBarcodeMaChineIdNearThirtyDay(list); //查询档口id数组近一个月的全部记录

		ArrayList<BarcodeCountVO> vos = new ArrayList<>(); //封装成前端需要的数据格式

		getResult(list, records, vos);
		return vos;

	}

	public BarcodeCountVO findByNameAndTime2() {
		List<Stalls> all = stallsDao.findAll();  //全部档口
		List<Integer> list = all.stream().map(s -> s.getId()).collect(Collectors.toList()); //获取全部档口的id
		List<Record> records = recordDao.findByBarcodeMaChineIdNearThirtyDay(list); //查询档口id数组近30天
		BarcodeCountVO res = new BarcodeCountVO(); //创建vo封装数据
		res.setStallsName("全部档口");
		int size = records.size();
		res.setBarcodCount(Long.valueOf(size+""));
		return res;
	}
	//根据 档口名和联系人查询某段时间的条码
	public List<BarcodeCountVO> findByNameAndTime(String stallName, String linkName, String startDate, String endDate) {
		//匹配档口名
		if (!StringUtils.isEmpty(stallName)) {
			//档口名不为空 判断联系人是为空
			//1.根据档口名字或者联系人名字模糊匹配出档口id
			List<Integer> list = stallsDao.findIdByStallName(stallName);
			if (StringUtils.isEmpty(linkName)){ //联系人为空
				//2.查询出这些档口近一个月的条码
				List<Record> all = recordDao.findByBarcodeMaChineIdNearThirtyDay(list,startDate+" 00:00:00",endDate+" 23:59:59");
				//3.分类进行封装 封装成前端需要的格式
				ArrayList<BarcodeCountVO> vos = new ArrayList<>();
				getResult(list, all, vos);
				return vos;
			}else { //联系人不为空
				List<Integer> list2 = stallsDao.findIdByStallName(linkName);
				List<Integer> sandId = getSandId(list, list2); //获取交集
				//2.查询出这些档口近一个月的条码
				List<Record> all = recordDao.findByBarcodeMaChineIdNearThirtyDay(sandId,startDate+" 00:00:00",endDate+" 23:59:59");
				//3.分类进行封装 封装成前端需要的格式
				ArrayList<BarcodeCountVO> vos = new ArrayList<>();
				getResult(sandId, all, vos);
				return vos;
			}

		}else {
			//档口名为空
			if (StringUtils.isEmpty(linkName)){ //联系人为空
				//返回空
				return null;
			}else { //联系人不为空
				List<Integer> list3 = stallsDao.findIdByUserName(linkName);

				//2.查询出这些档口近一个月的条码
				List<Record> all = recordDao.findByBarcodeMaChineIdNearThirtyDay(list3,startDate+" 00:00:00",endDate+" 23:59:59");
				//3.分类进行封装 封装成前端需要的格式
				ArrayList<BarcodeCountVO> vos = new ArrayList<>();
				getResult(list3, all, vos);
				return vos;
			}
		}

	}

	private List<Integer> getSandId(List<Integer> list, List<Integer> list2) {
		List<Integer> collect = list.stream().filter(s -> list2.contains(s)).collect(Collectors.toList());
		return collect;
	}

    public Info getInfo(String barcodeNumber) {
		barcodeNumber = barcodeNumber.substring(0,15);
		Record record = recordDao.findAllByBarcode(barcodeNumber + "%");
		Info info = new Info();
		if (record == null){
			throw new MyException(500,"该二维码无效！");
		}else {
			//查询档口信息
			Stalls stalls = stallsDao.findInfoById(record.getStallsId());
			StallsVo stallsVo = new StallsVo();
			if (stalls == null){
//			throw new MyException(500,"档口信息为空");
//				System.out.println("aaaaa");
			}else {
				BeanUtils.copyProperties(stalls, stallsVo);
				stallsVo.setUserName(stallsDao.findUserNameById(stalls.getUserId()));
				stallsVo.setSlaughterHouseName(slaughterHouseDao.findNameById(Integer.parseInt(stalls.getSlaughterHouseId())));
			}
			//查询禽类信息
			PoultryCategory poultryCategory = poultryCategoryDao.findById(record.getPoultryCategoryId());
			PoultryCategoryVo poultryCategoryVo = new PoultryCategoryVo();
			if (poultryCategory == null){
//			throw  new MyException(500,"禽类信息为空");
			}else {

				BeanUtils.copyProperties(poultryCategory,poultryCategoryVo);
			}

			//查询市场信息
			SlaughterHouse slaughterHouse = slaughterHouseDao.findSlaughterById(stalls.getSlaughterHouseId());
			SlaughterVo slaughterVo = new SlaughterVo();
			if (slaughterHouse == null){
//			throw new MyException(500,"市场信息为空！");
			}else {

				BeanUtils.copyProperties(slaughterHouse,slaughterVo);
			}
			//查询贴标时间
			info.setRecord(record);

			info.setStallsVo(stallsVo);
			info.setPoultryCategoryVo(poultryCategoryVo);
			info.setSlaughterVo(slaughterVo);
		}
		return info;
	}
}
